#define MXMODULE_MEMTYPE

#include "deds/memtype.h"
#include <assert.h>
#include <string.h>

MX_ALLOCATOR mx_stdalloc = { {{malloc, realloc, free}
							  }
};

typedef struct MX__ALLOCATOR_MEMORY {
	union {
		char a;
		unsigned char b;
		short c;
		unsigned short d;
		int e;
		unsigned int f;
		long g;
		unsigned long h;
		float i;
		double j;
		char dat[2];
		void *k;
		int *l;
	} alignment;
	MX_ALLOCATOR_DATA *alloc;
	size_t bytes;
#ifndef NDEBUG
	unsigned long magic;
#endif
} MX__ALLOCATOR_MEMORY;

void *mx_memalloc(size_t bytes, MX_ALLOCATOR_DATA * allocator)
{
	MX__ALLOCATOR_MEMORY *mem;

	if (!allocator)
		allocator = &mx_stdalloc.base.alloc;

	assert(allocator->alloc);
	mem = allocator->alloc(sizeof(MX__ALLOCATOR_MEMORY) + bytes);
	assert(mem);

	memset(mem, 0, sizeof(MX__ALLOCATOR_MEMORY));
	mem->alloc = allocator;
	mem->bytes = bytes;
#ifndef NDEBUG
	mem->magic = 0xdeafd00dl;
#endif
	return &mem[1];
}

void *mx_memrealloc(void *ptr, size_t bytes)
{
	MX__ALLOCATOR_MEMORY *ret;
	MX__ALLOCATOR_MEMORY *mem = (MX__ALLOCATOR_MEMORY *) ptr - 1;

	assert(ptr);
	assert(mem);
	assert(mem->magic);
	assert(mem->magic == 0xdeafd00dl);
	assert(mem->alloc->realloc);
	ret = mem->alloc->realloc(mem, sizeof(MX__ALLOCATOR_MEMORY) + bytes);
	mem->bytes = bytes;
	assert(ret);

	return &ret[1];
}

void mx_memfree(void *ptr)
{
	MX__ALLOCATOR_MEMORY *mem = (MX__ALLOCATOR_MEMORY *) ptr - 1;
	const int bytes = mem->bytes;

	assert(ptr);
	assert(mem);
	assert(mem->magic);
	assert(mem->magic == 0xdeafd00dl);
	if (mem->alloc->free)
		mem->alloc->free(mem);

	memset(mem, 0, sizeof(MX__ALLOCATOR_MEMORY) + bytes);
}

/*
   DEDS
   Data structures and utility functions for C
   Copyright (C) 2006 Douglas Eleveld

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
